
package com.studiofortress.sf.util;

/**
 * The trivial SmallPoint describes the X and Y location of something. It is
 * designed to be the fastest and smallest possible object to simply hold the X
 * and Y values together.
 * 
 * @author Joseph Lenton
 */
public class SmallPoint implements Comparable<SmallPoint>
{
    private final int x;
    private final int y;
    
    /**
     * The given values are rounded to the nearest int.
     * @param x The X location of this point.
     * @param y The Y location of this point.
     */
    public SmallPoint(final float x, final float y)
    {
        this( Math.round(x), Math.round(y) );
    }

    /**
     * Creates a new point at the location given.
     * @param x The X location of this point.
     * @param y The Y location of this point.
     */
    public SmallPoint(final int x, final int y)
    {
        this.x = x;
        this.y = y;
    }

    /**
     * @return The x location of this point.
     */
    public int getX()
    {
        return x;
    }

    /**
     * @return The y location of this point.
     */
    public int getY()
    {
        return y;
    }
    
    /**
     * @param other The point to test against.
     * @return True if other is a SmallPoint and has the same location as this point, otherwise false.
     */
    @Override
    public boolean equals(final Object other)
    {
        if (other instanceof SmallPoint) {
            final SmallPoint otherPoint = (SmallPoint) other;
            return getX() == otherPoint.getX() && getY() == otherPoint.getY();
        } else {
            return false;
        }
    }

    /**
     * This uses the hashcode for the comparison.
     * @param other
     * @return
     */
    @Override
    public int compareTo(final SmallPoint other)
    {
        return hashCode() - other.hashCode();
    }

    /**
     * The hash code is generated by bitwise-or'ing the bottom 16 bits of this
     * points x location with the bottom 16 bits of this points y location.
     * @return X in the upper 16 bits, Y in the lower 16 bits.
     */
    @Override
    public int hashCode()
    {
        return ((getX() << 16) & 0xFFFF0000) | (getY() & 0x0000FFFF);
    }

    /**
     * This should only be used for display and debugging purposes only. There
     * are no guarantees that the format that this is returned in will stay the
     * same in future versions.
     * @return The location that this point represents.
     */
    @Override
    public String toString()
    {
        return "x: " + getX() + ", y: " + getY();
    }
}
